home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
Gfx
/
Edit
/
TSMorph
/
src
/
RGBToScreen020.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-30
|
12KB
|
476 lines
// TSMorph - Amiga Morphing program
// Copyright (C) © 1993 Topicsave Limited
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// mpaddock@cix.compulink.co.uk
// include precompiled code if required
#ifndef TSMORPH_H
#include "TSMorph.h"
#endif
// The two functions in this file are exact clones of those in OpalLoad.c
// but This code is compiled with -m2 -O -mt
// and is only called if at least a 020 is present
void
RGBToScreen020(UBYTE *red,UBYTE *green,UBYTE *blue,UWORD Height,UWORD Width,
UWORD maxcol,UWORD xadd,UBYTE *r,UBYTE *g,UBYTE *b) {
UWORD i,j,k;
ULONG maxdiff;
ULONG diff;
LONG t;
UWORD index;
for (j = 0;
j < Height;
++j) {
if (ProgressWnd) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
GTSL_Level,(ULONG)j,TAG_END);
HandleProgressIDCMP();
}
for (i = 0;
i < Width;
++i) {
// Find closest color
maxdiff = 0x7FFFFFFF;
for (k = 0;
k < maxcol;
++k) {
t = *red - r[k];
diff = t*t*3;
t = *green - g[k];
diff += (t*t*6);
t = *blue - b[k];
diff += (t*t);
if (diff < maxdiff) {
maxdiff = diff;
index = k;
}
}
// Store index to color
*red = index;
++red;
++green;
++blue;
}
red += xadd;
green += xadd;
blue += xadd;
if (ProgressWnd) {
HandleProgressIDCMP();
}
}
}
void
PaletteToScreen020(struct RastPort *Rp,struct Picture *pic,UWORD maxcol,
UBYTE *r,UBYTE *g,UBYTE *b) {
UWORD i,j,k; // loop counters
LONG penno;
UBYTE rr,gg,bb;
ULONG maxdiff;
ULONG diff;
UWORD index;
LONG t; // temp diff
UWORD EHB;
BOOL isHAM6 = FALSE;
BOOL isHAM8 = FALSE;
BOOL isEHB = FALSE;
struct DisplayInfo queryinfo;
DisplayInfoHandle handle;
struct BitMap BM;
UBYTE *arrayp;
ULONG NewPen[256];
InitBitMap(&BM,pic->ilbm->Bmhd.nPlanes,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
RP.BitMap = &BM;
InitBitMap(&TBM,pic->ilbm->Bmhd.nPlanes,pic->ilbm->Bmhd.w,1);
TRP.BitMap = &TBM;
TBM.Planes[0]=plane0;
TBM.Planes[1]=plane1;
TBM.Planes[2]=plane2;
TBM.Planes[3]=plane3;
TBM.Planes[4]=plane4;
TBM.Planes[5]=plane5;
TBM.Planes[6]=plane6;
TBM.Planes[7]=plane7;
if ((handle = FindDisplayInfo(pic->ilbm->camg)) &&
(GetDisplayInfoData(handle,(UBYTE *)&queryinfo,sizeof(queryinfo),DTAG_DISP,NULL))) {
if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
GTTX_Text,(ULONG)MyGetMsg(MSG_REMAPH6),
TAG_END);
isHAM6 = TRUE;
}
else {
if ((pic->ilbm->Bmhd.nPlanes == 8) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
isHAM8 = TRUE;
GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
GTTX_Text,(ULONG)MyGetMsg(MSG_REMAPH8),
TAG_END);
}
else {
if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_EXTRAHALFBRITE)) {
isEHB = TRUE;
GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
GTTX_Text,(ULONG)MyGetMsg(MSG_REMAPEHB),
TAG_END);
}
else {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
GTTX_Text,(ULONG)MyGetMsg(MSG_REMAPIL),
TAG_END);
for (i = 0;
(i < pic->ilbm->ncolors);
i++) {
maxdiff = 0x7FFFFFFF;
for (k = 0;
k < maxcol;
++k) {
t = pic->ilbm->RGB[i*4+1] - r[k];
diff = t*t*3;
t = pic->ilbm->RGB[i*4+2] - g[k];
diff += (t*t*6);
t = pic->ilbm->RGB[i*4+3] - b[k];
diff += (t*t);
if (diff < maxdiff) {
maxdiff = diff;
NewPen[i] = k;
}
}
}
}
}
}
}
for (j = 0;
j < pic->ilbm->Bmhd.h;
++j) {
if (ProgressWnd) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
GTSL_Level,(ULONG)j,TAG_END);
HandleProgressIDCMP();
}
ReadPixelLine8(Rp,0,j,pic->ilbm->Bmhd.w,Array,&TRP);
arrayp = Array;
if (isHAM6) {
rr = gg = bb = 0;
for (i = 0;
i < pic->ilbm->Bmhd.w;
++i) {
penno = *arrayp;
switch (penno & 0x30) {
case 0:
rr = pic->ilbm->RGB[penno*4+1];
gg = pic->ilbm->RGB[penno*4+2];
bb = pic->ilbm->RGB[penno*4+3];
break;
case 0x10:
bb = (penno&0xf)|((penno&0xf)<<4);
break;
case 0x20:
rr = (penno&0xf)|((penno&0xf)<<4);
break;
case 0x30:
gg = (penno&0xf)|((penno&0xf)<<4);
break;
}
// Find closest color
maxdiff = 0x7FFFFFFF;
for (k = 0;
k < maxcol;
++k) {
t = rr - r[k];
diff = t*t*3;
t = gg - g[k];
diff += (t*t*6);
t = bb - b[k];
diff += (t*t);
if (diff < maxdiff) {
maxdiff = diff;
index = k;
}
}
*arrayp++ = index;
}
}
else {
if (isHAM8) {
rr = gg = bb = 0;
for (i = 0;
i < pic->ilbm->Bmhd.w;
++i) {
penno = *arrayp;
switch (penno & 0xc0) {
case 0:
rr = pic->ilbm->RGB[penno*4+1];
gg = pic->ilbm->RGB[penno*4+2];
bb = pic->ilbm->RGB[penno*4+3];
break;
case 0x40:
bb = (penno&0x3f)<<2;
break;
case 0x80:
rr = (penno&0x3f)<<2;
break;
case 0xc0:
gg = (penno&0x3f)<<2;
break;
}
// Find closest color
maxdiff = 0x7FFFFFFF;
for (k = 0;
k < maxcol;
++k) {
t = rr - r[k];
diff = t*t*3;
t = gg - g[k];
diff += (t*t*6);
t = bb - b[k];
diff += (t*t);
if (diff < maxdiff) {
maxdiff = diff;
index = k;
}
}
*arrayp++ = index;
}
}
else {
if (isEHB) {
for (i = 0;
i < pic->ilbm->Bmhd.w;
++i) {
penno = *arrayp;
EHB = (penno & 0x20)?1:0;
penno &= 0x1f;
rr = pic->ilbm->RGB[penno*4+1]>>EHB;
gg = pic->ilbm->RGB[penno*4+2]>>EHB;
bb = pic->ilbm->RGB[penno*4+3]>>EHB;
// Find closest color
maxdiff = 0x7FFFFFFF;
for (k = 0;
k < maxcol;
++k) {
t = rr - r[k];
diff = t*t*3;
t = gg - g[k];
diff += (t*t*6);
t = bb - b[k];
diff += (t*t);
if (diff < maxdiff) {
maxdiff = diff;
index = k;
}
}
*arrayp++ = index;
}
}
else {
for (i = 0;
i < pic->ilbm->Bmhd.w;
++i) {
penno = *arrayp;
*arrayp++ = NewPen[penno];
}
}
}
}
WritePixelLine8(Rp,0,j,pic->ilbm->Bmhd.w,Array,&TRP);
}
}
void
PaletteToEGS020(struct RastPort *Rp,struct Picture *pic,UBYTE *plane,UBYTE *r,UBYTE *g,UBYTE *b) {
UWORD i,j; // loop counters
LONG penno;
UBYTE rr,gg,bb;
UWORD EHB;
BOOL isHAM6 = FALSE;
BOOL isHAM8 = FALSE;
BOOL isEHB = FALSE;
struct DisplayInfo queryinfo;
DisplayInfoHandle handle;
struct BitMap BM;
UBYTE *arrayp;
// Initialise stuff
InitBitMap(&BM,pic->ilbm->Bmhd.nPlanes,pic->ilbm->Bmhd.w,pic->ilbm->Bmhd.h);
RP.BitMap = &BM;
InitBitMap(&TBM,pic->ilbm->Bmhd.nPlanes,pic->ilbm->Bmhd.w,1);
TRP.BitMap = &TBM;
TBM.Planes[0]=plane0;
TBM.Planes[1]=plane1;
TBM.Planes[2]=plane2;
TBM.Planes[3]=plane3;
TBM.Planes[4]=plane4;
TBM.Planes[5]=plane5;
TBM.Planes[6]=plane6;
TBM.Planes[7]=plane7;
// based on CAMG chunk determine special type of image
if ((handle = FindDisplayInfo(pic->ilbm->camg)) &&
(GetDisplayInfoData(handle,(UBYTE *)&queryinfo,sizeof(queryinfo),DTAG_DISP,NULL))) {
// 6 plane HAM
if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
GTTX_Text,(ULONG)"Converting HAM6 to EGS",
TAG_END);
isHAM6 = TRUE;
}
else {
// 8 plane HAM
if ((pic->ilbm->Bmhd.nPlanes == 8) && (queryinfo.PropertyFlags & DIPF_IS_HAM)) {
isHAM8 = TRUE;
GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
GTTX_Text,(ULONG)"Converting HAM8 to EGS",
TAG_END);
}
else {
// 6 plane EHB
if ((pic->ilbm->Bmhd.nPlanes == 6) && (queryinfo.PropertyFlags & DIPF_IS_EXTRAHALFBRITE)) {
isEHB = TRUE;
GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
GTTX_Text,(ULONG)"Converting EHB to EGS",
TAG_END);
}
else {
// standard ILBM
GT_SetGadgetAttrs(ProgressGadgets[GDX_Mess],ProgressWnd,NULL,
GTTX_Text,(ULONG)"Converting ILBM to EGS",
TAG_END);
}
}
}
}
// for each line
for (j = 0;
j < pic->ilbm->Bmhd.h;
++j) {
if (ProgressWnd) {
GT_SetGadgetAttrs(ProgressGadgets[GDX_Pass2],ProgressWnd,NULL,
GTSL_Level,(ULONG)j,TAG_END);
HandleProgressIDCMP();
}
// convert line to chunky
ReadPixelLine8(Rp,0,j,pic->ilbm->Bmhd.w,Array,&TRP);
arrayp = Array;
// for each pixel depending on mode convert to EGS
if (isHAM6) {
// rgb = 0 at start of line
rr = gg = bb = 0;
for (i = 0;
i < pic->ilbm->Bmhd.w;
++i) {
penno = *arrayp;
switch (penno & 0x30) { // HAM selection
case 0:
rr = pic->ilbm->RGB[penno*4+1];
gg = pic->ilbm->RGB[penno*4+2];
bb = pic->ilbm->RGB[penno*4+3];
break;
case 0x10:
bb = (penno&0xf)|((penno&0xf)<<4);
break;
case 0x20:
rr = (penno&0xf)|((penno&0xf)<<4);
break;
case 0x30:
gg = (penno&0xf)|((penno&0xf)<<4);
break;
}
*plane++ = rr;
*plane++ = gg;
*plane++ = bb;
plane++;
arrayp++;
}
}
else {
if (isHAM8) {
// very similar to HAM6
rr = gg = bb = 0;
for (i = 0;
i < pic->ilbm->Bmhd.w;
++i) {
penno = *arrayp;
switch (penno & 0xc0) {
case 0:
rr = pic->ilbm->RGB[penno*4+1];
gg = pic->ilbm->RGB[penno*4+2];
bb = pic->ilbm->RGB[penno*4+3];
break;
case 0x40:
bb = (penno&0x3f)<<2;
break;
case 0x80:
rr = (penno&0x3f)<<2;
break;
case 0xc0:
gg = (penno&0x3f)<<2;
break;
}
*plane++ = rr;
*plane++ = gg;
*plane++ = bb;
plane++;
arrayp++;
}
}
else {
if (isEHB) {
// simple - just check highest plane and divide by two if required
for (i = 0;
i < pic->ilbm->Bmhd.w;
++i) {
penno = *arrayp;
EHB = (penno & 0x20)?1:0;
penno &= 0x1f;
rr = pic->ilbm->RGB[penno*4+1]>>EHB;
gg = pic->ilbm->RGB[penno*4+2]>>EHB;
bb = pic->ilbm->RGB[penno*4+3]>>EHB;
*plane++ = rr;
*plane++ = gg;
*plane++ = bb;
plane++;
arrayp++;
}
}
else {
// simple palette remap
for (i = 0;
i < pic->ilbm->Bmhd.w;
++i) {
penno = *arrayp;
rr = pic->ilbm->RGB[penno*4+1];
gg = pic->ilbm->RGB[penno*4+2];
bb = pic->ilbm->RGB[penno*4+3];
*plane++ = rr;
*plane++ = gg;
*plane++ = bb;
plane++;
arrayp++;
}
}
}
}
plane += (pic->EGS_BitMap->BytesPerRow - (4*pic->ilbm->Bmhd.w));
}
}